

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/fluid.png">
  <link rel="icon" href="/img/fluid.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="John Doe">
  <meta name="keywords" content="">
  
    <meta name="description" content="@[TOC] 一、参考资料  视频资料  二、运行环境  Windows11 Visual Studio Code v2022 Node.js v16.5.01 Vue&#x2F;cli v5.0.6 Bootstrap 5.1.3  三、Vue2插槽 Vue2 实现了一套内容分发的 API，，将 &lt;slot&gt;元素作为承载分发内容的出口。 作用： 父组件通过定义插槽向子组件中传递定制化">
<meta property="og:type" content="article">
<meta property="og:title" content="Vue2 笔记3 Vue2三种slot插槽的概念与运用 _ ES6 对象的解构赋值 _ 基于Vue2使用axios发送请求实现GitHub案例 _ 浏览器跨域问题与解决">
<meta property="og:url" content="http://example.com/2022/07/24/Vue2%20%E7%AC%94%E8%AE%B03%20Vue2%E4%B8%89%E7%A7%8Dslot%E6%8F%92%E6%A7%BD%E7%9A%84%E6%A6%82%E5%BF%B5%E4%B8%8E%E8%BF%90%E7%94%A8%20_%20ES6%20%E5%AF%B9%E8%B1%A1%E7%9A%84%E8%A7%A3%E6%9E%84%E8%B5%8B%E5%80%BC%20_%20%E5%9F%BA%E4%BA%8EVue2%E4%BD%BF%E7%94%A8axios%E5%8F%91%E9%80%81%E8%AF%B7%E6%B1%82%E5%AE%9E%E7%8E%B0GitHub%E6%A1%88%E4%BE%8B%20_%20%E6%B5%8F%E8%A7%88%E5%99%A8%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98%E4%B8%8E%E8%A7%A3%E5%86%B3/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="@[TOC] 一、参考资料  视频资料  二、运行环境  Windows11 Visual Studio Code v2022 Node.js v16.5.01 Vue&#x2F;cli v5.0.6 Bootstrap 5.1.3  三、Vue2插槽 Vue2 实现了一套内容分发的 API，，将 &lt;slot&gt;元素作为承载分发内容的出口。 作用： 父组件通过定义插槽向子组件中传递定制化">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://img-blog.csdnimg.cn/492e38dd3f49484e84a744db605e1175.png#=50%x">
<meta property="og:image" content="https://img-blog.csdnimg.cn/9a7ae2f9da764283862164c893506192.gif#pic_center">
<meta property="og:image" content="https://img-blog.csdnimg.cn/3fa4d9ce58da4d038f3db1aedffb540a.png">
<meta property="og:image" content="https://img-blog.csdnimg.cn/a12456f304634e3098ffa278e7195fc1.png">
<meta property="og:image" content="https://img-blog.csdnimg.cn/25b0e3c779ac481688dee7f22291b963.png">
<meta property="article:published_time" content="2022-07-24T07:39:25.000Z">
<meta property="article:modified_time" content="2022-08-22T15:49:30.309Z">
<meta property="article:author" content="John Doe">
<meta property="article:tag" content="Vue">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://img-blog.csdnimg.cn/492e38dd3f49484e84a744db605e1175.png#=50%x">
  
  
  
  <title>Vue2 笔记3 Vue2三种slot插槽的概念与运用 _ ES6 对象的解构赋值 _ 基于Vue2使用axios发送请求实现GitHub案例 _ 浏览器跨域问题与解决 - Hexo</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"example.com","root":"/","version":"1.9.2","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
  


  
<meta name="generator" content="Hexo 6.2.0"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>尤 Ni&#39;s Blog</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/img/default.png') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="Vue2 笔记3 Vue2三种slot插槽的概念与运用 _ ES6 对象的解构赋值 _ 基于Vue2使用axios发送请求实现GitHub案例 _ 浏览器跨域问题与解决"></span>
          
        </div>

        
          
  <div class="mt-3">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-author" aria-hidden="true"></i>
        John Doe
      </span>
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2022-07-24 15:39" pubdate>
          2022年7月24日 下午
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          29k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          244 分钟
        
      </span>
    

    
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">Vue2 笔记3 Vue2三种slot插槽的概念与运用 _ ES6 对象的解构赋值 _ 基于Vue2使用axios发送请求实现GitHub案例 _ 浏览器跨域问题与解决</h1>
            
              <p class="note note-info">
                
                  
                    本文最后更新于：1 小时前
                  
                
              </p>
            
            
              <div class="markdown-body">
                
                <p>@[TOC]</p>
<h1 id="一、参考资料"><a href="#一、参考资料" class="headerlink" title="一、参考资料"></a>一、参考资料</h1><hr>
<ul>
<li><a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1Zy4y1K7SH?p=98">视频资料</a></li>
</ul>
<h1 id="二、运行环境"><a href="#二、运行环境" class="headerlink" title="二、运行环境"></a>二、运行环境</h1><hr>
<ul>
<li>Windows11</li>
<li>Visual Studio Code v2022</li>
<li>Node.js v16.5.01</li>
<li>Vue&#x2F;cli v5.0.6</li>
<li>Bootstrap 5.1.3</li>
</ul>
<h1 id="三、Vue2插槽"><a href="#三、Vue2插槽" class="headerlink" title="三、Vue2插槽"></a>三、Vue2插槽</h1><hr>
<p>Vue2 实现了一套内容分发的 API，，将 <code>&lt;slot&gt;</code>元素作为承载分发内容的出口。</p>
<p><strong>作用：</strong> 父组件通过定义插槽向子组件中传递定制化的内容（数据或函数）。</p>
<h2 id="3-1-默认插槽"><a href="#3-1-默认插槽" class="headerlink" title="3.1 默认插槽"></a>3.1 默认插槽</h2><p>接下来举一个案例来体现插槽的作用。</p>
<p>比如在App组件中：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p>我定义了一个模板，里面有一个div，div里面引入了自定义的Vue组件Header</p>
<p>如果我想在App组件里引入Header组件，并向里面添加内容，比如：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><br>	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span> 搜索引擎 <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p>在默认情况下，<code>&lt;h1&gt;</code>是不会渲染出来的，当然其他普通的HTML元素也不会渲染，此时就可以使用Vue提供的 slot 插槽，我们放一个插槽在这个Header组件里面，类似这样：</p>
<p>（如果引入Header组件时，里面没有内容，那么就会出现Header里<code>&lt;slot&gt;</code>标签的内容：”插槽为空”</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">slot</span>&gt;</span>插槽为空<span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>这仿佛就是在提示Vue：<code>&lt;slot&gt;</code> 这里是一个待填的坑，将由父组件来填。</p>
<p>由于是父组件来填的，所以 slot 插槽可用于父组件向子组件传递数据。</p>
<p>注意，通过 slot 插槽渲染的元素，其样式可以通过父组件来设置。</p>
<h2 id="3-2-具名插槽"><a href="#3-2-具名插槽" class="headerlink" title="3.2 具名插槽"></a>3.2 具名插槽</h2><p><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-slots.html#%E5%85%B7%E5%90%8D%E6%8F%92%E6%A7%BD">具名插槽</a></p>
<p>据Vue官方的文档介绍，所谓的具名插槽其实就是有name属性值的插槽，（从vue2.6.0开始，默认的插槽的name值为default），比如我们可以在同一个组件中设置多个插槽，这样这个组件的父组件就可以向不同的插槽里插入元素。</p>
<p>同样以App组件 和 Header组件为例。</p>
<p>Header 子组件：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;a&quot;</span>&gt;</span>插槽a为空<span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;c&quot;</span>&gt;</span>插槽c为空<span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>App父组件：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">&quot;a&quot;</span>&gt;</span>插槽a<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">&quot;c&quot;</span>&gt;</span>插槽c 内容1<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">&quot;c&quot;</span>&gt;</span>插槽c 内容2<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>上述App组件中的h1标签可以是其他的HTML标签。</p>
<p>这里指定的slot是可以复用的，不过插入相同插槽的元素可以用template标签来指定子组件的插槽，上述App组件代码的简写形式如下：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">&quot;a&quot;</span>&gt;</span>插槽a<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">&quot;c&quot;</span>&gt;</span><br>    		<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>插槽c 内容1<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    		<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>插槽c 内容2<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    	<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p><font color="red" size="3">注意：上述在template直接使用slot的写法已经在Vue2.6.0 起被废弃 <a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-slots.html#%E5%B8%A6%E6%9C%89-slot-attribute-%E7%9A%84%E5%85%B7%E5%90%8D%E6%8F%92%E6%A7%BD">查看文档</a></font></p>
<p>Vue2.6.0 版本以后的 <strong>具名插槽</strong> 用法如下 <a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-slots.html#%E5%85%B7%E5%90%8D%E6%8F%92%E6%A7%BD">查看文档</a>：</p>
<p>声明插槽的方式不变（不过添加了default默认的插槽机制）：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 插槽名为 slot1 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;slot1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 插槽名默认为default --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">slot</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p>父组件在引入指定插槽时候，template指定插槽时必须使用 <code>v-slot</code> ，类似于 v-on 的<code>@</code>和 v-bind的<code>:</code>，<code>v-slot </code>其简写形式为 <code>#</code>，比如：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">&quot;a&quot;</span>&gt;</span>插槽a<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">template</span> #<span class="hljs-attr">c</span>&gt;</span><br>    		<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>插槽c 内容1<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    		<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>插槽c 内容2<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    	<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><font color="red" size="3">注意: v-slot 属性只支持 <code> &lt;template&gt;</code>标签 </font></p>
<p>同时， 由于插槽默认名称为 “default “，所以父组件可以指定默认插槽的内容：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">v-slot:default</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>插槽c 内容1<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>插槽c 内容2<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>   <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br><br><span class="hljs-comment">&lt;!-- 简写形式如下 --&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">template</span> #<span class="hljs-attr">defualt</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>插槽c 内容1<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>插槽c 内容2<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>   <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br></code></pre></td></tr></table></figure>

<h2 id="3-3-作用域插槽"><a href="#3-3-作用域插槽" class="headerlink" title="3.3 作用域插槽"></a>3.3 作用域插槽</h2><p>使用场景：父组件渲染元素时候会用到子组件的数据，此时可通过作用域插槽，将设置插槽的子组件里的数据传给父组件，方便父组件往子组件里设置元素。</p>
<p>在Vue2中引入子组件时，父组件可以通过:Key&#x3D;Value来传值，比如在App组件中：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">Header</span> <span class="hljs-attr">:name</span>=<span class="hljs-string">&quot;uni&quot;</span>/&gt;</span><br></code></pre></td></tr></table></figure>
<p>这里在引入Header组件的同时，传入了名为name，值为”uni”的变量。</p>
<p>然后在Header组件中就可以通过 <code>&#123;&#123; name &#125;&#125; </code>直接获取这个值。</p>
<p>而 <code>&lt;slot&gt;</code> 标签也可以通过这种方式传入数据，比如在Header子组件中：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">:name</span>=<span class="hljs-string">&quot;uni&quot;</span>&gt;</span>插槽a为空<span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p>这个 name变量就会传入到引入这个Header组件的父组件 App，然后父组件App在写插槽元素时就可以获取到数据了：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><br>    	<span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">slot-scope</span>=<span class="hljs-string">&quot;data&quot;</span>&gt;</span><br>    		<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span> &#123;&#123; data.name &#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    	<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p>这里的 slot-scope 声明了被接收的 prop 对象会作为 slotProps 变量存在于 <template> 作用域中。我们可以像命名 JavaScript 函数参数一样随意命名 data。</p>
<p>说起来可能会比较绕，简单理解就是作用域插槽，可以让子组件传递数据给父组件，不过父组件只能在引入该组件标签的内部获取到数据。</p>
<p>绑定在 <code>&lt;slot&gt;</code> 元素上的 attribute 被称为 <strong>插槽 prop</strong>。</p>
<p>关于作用域插槽，官方提到的一句很重要的话：</p>
<ul>
<li><p><font color="red"> 父级模板里的所有内容都是在父级作用域中编译的；</font></p>
</li>
<li><p><font color="red"> 子模板里的所有内容都是在子作用域中编译的。</font></p>
</li>
</ul>
<p><font color="red"> 注意：以上通过 slot-scope来指定作用域的方法自Vue2.6.0开始已被废弃 <a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-slots.html#%E5%B8%A6%E6%9C%89-slot-scope-attribute-%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%8F%92%E6%A7%BD">官方文档</a></font></p>
<p>接下来是Vue2最新版本的作用域插槽用法 <a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-slots.html#%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%8F%92%E6%A7%BD">官方文档</a></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">v-slot:default</span>=<span class="hljs-string">&quot;data&quot;</span>&gt;</span><br>  &#123;&#123; data.name &#125;&#125;<br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><br><span class="hljs-comment">&lt;!-- 简写形式如下: --&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">template</span> #<span class="hljs-attr">default</span>=<span class="hljs-string">&quot;data&quot;</span>&gt;</span><br>  &#123;&#123; data.name &#125;&#125;<br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>其实这里和之前差不多，新版本的改动就是 template必须使用v-slot来指定插槽，或者指定插槽引入的数据。</p>
<p>和默认插槽一样，如果在引入数据时没有指定插槽名称，那么数据将从默认插槽中获取</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">v-slot</span>=<span class="hljs-string">&quot;data&quot;</span>&gt;</span><br>  &#123;&#123; data.name &#125;&#125;<br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>这里需要注意 <code>v-slot=&quot;data&quot;</code>  和 <code>v-slot:default</code> 二者的区别，前者是从默认插槽里获取数据，定义为data，后者是指定为默认插槽。</p>
<h3 id="ES6解构赋值概念-amp-作用域插槽的解构赋值"><a href="#ES6解构赋值概念-amp-作用域插槽的解构赋值" class="headerlink" title="ES6解构赋值概念 &amp; 作用域插槽的解构赋值"></a>ES6解构赋值概念 &amp; 作用域插槽的解构赋值</h3><p><a target="_blank" rel="noopener" href="https://www.runoob.com/w3cnote/deconstruction-assignment.html">ES6的解构赋值</a></p>
<figure class="highlight x86asm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs x86asm">“ES6是门脚本语言,从名字(ECMAScript6)中我们可以看出,他是<span class="hljs-keyword">JS</span>的组成部分,直白点说,它规定了我们怎样写<span class="hljs-keyword">JS</span>。”<br></code></pre></td></tr></table></figure>

<p>ES6解构赋值，是指我们在写JavaScript代码时可以实现的一些特殊机制。</p>
<p>在解构中，有下面两部分参与：</p>
<ul>
<li>解构的源，解构赋值表达式的右边部分。</li>
<li>解构的目标，解构赋值表达式的左边部分。</li>
</ul>
<p>在Vue2作用域插槽中的解构赋值，是将参数值转为的Object对象，所以我们先主要了解ES6关于对象的解构赋值的一些机制：<br>（这里注意，等式的左边相当于子组件在定义slot标签时传入的参数，等式的右边则相当于父组件在插入元素到指定slot时，在v-slot:xxx&#x3D;”Object” 中的Object）</p>
<ul>
<li>基本的解构</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> &#123; foo, bar &#125; = &#123; <span class="hljs-attr">foo</span>: <span class="hljs-string">&#x27;aaa&#x27;</span>, <span class="hljs-attr">bar</span>: <span class="hljs-string">&#x27;bbb&#x27;</span> &#125;;<br><span class="hljs-comment">// foo = &#x27;aaa&#x27;</span><br><span class="hljs-comment">// bar = &#x27;bbb&#x27;</span><br> <br><span class="hljs-keyword">let</span> &#123; baz : foo &#125; = &#123; baz : <span class="hljs-string">&#x27;ddd&#x27;</span> &#125;;<br><span class="hljs-comment">// foo = &#x27;ddd&#x27; , 可理解为替换了Key=baz的Value</span><br></code></pre></td></tr></table></figure>
<ul>
<li><p>可嵌套可忽略</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> obj = &#123;<span class="hljs-attr">p</span>: [<span class="hljs-string">&#x27;hello&#x27;</span>, &#123;<span class="hljs-attr">y</span>: <span class="hljs-string">&#x27;world&#x27;</span>&#125;] &#125;;<br><span class="hljs-keyword">let</span> &#123;<span class="hljs-attr">p</span>: [x, &#123; y &#125;] &#125; = obj;<br><span class="hljs-comment">// obj.x = &#x27;hello&#x27;</span><br><span class="hljs-comment">// obj.y = &#x27;world&#x27;</span><br><span class="hljs-comment">// PS: 之前我们使用的作用域插槽就类似于这种，父组件只接收数据赋值为 obj , 然后我们通过obj来调用子组件在&lt;slot&gt;里面指定的属性</span><br><span class="hljs-keyword">let</span> obj = &#123;<span class="hljs-attr">p</span>: [<span class="hljs-string">&#x27;hello&#x27;</span>, &#123;<span class="hljs-attr">y</span>: <span class="hljs-string">&#x27;world&#x27;</span>&#125;] &#125;;<br><span class="hljs-keyword">let</span> &#123;<span class="hljs-attr">p</span>: [x, &#123;  &#125;] &#125; = obj;<br><span class="hljs-comment">// x = &#x27;hello&#x27;</span><br></code></pre></td></tr></table></figure></li>
<li><p>不完全解构</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> obj = &#123;<span class="hljs-attr">p</span>: [&#123;<span class="hljs-attr">y</span>: <span class="hljs-string">&#x27;world&#x27;</span>&#125;] &#125;;<br><span class="hljs-keyword">let</span> &#123;<span class="hljs-attr">p</span>: [&#123; y &#125;, x ] &#125; = obj;<br><span class="hljs-comment">// x = undefined</span><br><span class="hljs-comment">// y = &#x27;world&#x27;</span><br><span class="hljs-comment">// 尽管obj里的p对象中只有一个元素，但是它同样可以赋值给具有两个元素的对象，多出来的对象就为undefined类型</span><br></code></pre></td></tr></table></figure>
</li>
<li><p>剩余运算符</p>
</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> &#123;a, b, ...rest&#125; = &#123;<span class="hljs-attr">a</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">b</span>: <span class="hljs-number">20</span>, <span class="hljs-attr">c</span>: <span class="hljs-number">30</span>, <span class="hljs-attr">d</span>: <span class="hljs-number">40</span>&#125;;<br><span class="hljs-comment">// a = 10</span><br><span class="hljs-comment">// b = 20</span><br><span class="hljs-comment">// rest = &#123;c: 30, d: 40&#125; 剩余的元素将以对象的形式赋值给rest</span><br></code></pre></td></tr></table></figure>

<ul>
<li>解构默认值（只会根据相应的Key进行替换，而不会替换整个Object对象）</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> &#123;a = <span class="hljs-number">10</span>, b = <span class="hljs-number">5</span>&#125; = &#123;<span class="hljs-attr">a</span>: <span class="hljs-number">3</span>&#125;;<br><span class="hljs-comment">// a = 3; b = 5;</span><br><span class="hljs-keyword">let</span> &#123;<span class="hljs-attr">a</span>: aa = <span class="hljs-number">10</span>, <span class="hljs-attr">b</span>: bb = <span class="hljs-number">5</span>&#125; = &#123;<span class="hljs-attr">a</span>: <span class="hljs-number">3</span>&#125;;<br><span class="hljs-comment">// aa = 3; bb = 5;</span><br></code></pre></td></tr></table></figure>
<p><strong>Array数组模型的解构和对象类似，不过多描述了，在Vue2中主要用到的是对象解构可以参考 <a target="_blank" rel="noopener" href="https://www.runoob.com/w3cnote/deconstruction-assignment.html">点击查看</a></strong></p>
<p>作用域插槽的内部工作原理是将插槽的内容包裹在一个拥有单个参数的函数里。</p>
<p><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-slots.html#%E8%A7%A3%E6%9E%84%E6%8F%92%E6%A7%BD-Prop"><strong>解构插槽 Prop</strong></a> ，这是官方在介绍作用域插槽时的拓展内容，我觉得有必要Mark一下，将来使用组件的时候可能会用到。</p>
<p>根据官方解释，我们举个实际的例子来理解一下这句话：</p>
<ul>
<li>子组件Header组件定义一个插槽</li>
</ul>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>头部<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;slot1&quot;</span> <span class="hljs-attr">:username</span>=<span class="hljs-string">&quot;username&quot;</span> <span class="hljs-attr">:age</span>=<span class="hljs-string">&quot;age&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span><br><span class="language-javascript">    <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;Header&#x27;</span>,</span><br><span class="language-javascript">    <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>)&#123;</span><br><span class="language-javascript">        <span class="hljs-keyword">return</span> &#123;</span><br><span class="language-javascript">            <span class="hljs-attr">username</span>: <span class="hljs-string">&#x27;uni&#x27;</span>,</span><br><span class="language-javascript">            <span class="hljs-attr">age</span>: <span class="hljs-string">&#x27;22&#x27;</span>,</span><br><span class="language-javascript">        &#125;</span><br><span class="language-javascript">    &#125;</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>
<ul>
<li>父组件App使用插槽（#是v-slot的缩写形式）<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;app&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><br>      <span class="hljs-comment">&lt;!-- 填补插槽 --&gt;</span><br>      <span class="hljs-comment">&lt;!-- </span><br><span class="hljs-comment">      &lt;template #slot1=&quot;data&quot;&gt;</span><br><span class="hljs-comment">          &lt;p&gt;不同的方式输出slot的数据: &#123;&#123;data&#125;&#125;&lt;/p&gt;</span><br><span class="hljs-comment">          &lt;p&gt;直接获取对象的属性: &#123;&#123;data.username&#125;&#125;&lt;/p&gt;</span><br><span class="hljs-comment">          &lt;p&gt;直接获取对象的属性: &#123;&#123;data.age&#125;&#125;&lt;/p&gt;</span><br><span class="hljs-comment">      &lt;/template&gt; </span><br><span class="hljs-comment">      --&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">template</span> #<span class="hljs-attr">slot1</span>=<span class="hljs-string">&quot;&#123;username, age, abc&#125;&quot;</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>不同的方式输出slot的数据: &#123;&#123;username&#125;&#125;, &#123;&#123;age&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>当获取不存在的参数时：&#123;&#123;typeof(abc)&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>      <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Header</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./components/Header.vue&#x27;</span></span><br><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span><br><span class="language-javascript">  <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;App&#x27;</span>,</span><br><span class="language-javascript">  <span class="hljs-attr">components</span>: &#123;<span class="hljs-title class_">Header</span>&#125;</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>
这里其实是将参数 username 和 age 包裹在一个函数中，类似下面的JS函数：<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> (<span class="hljs-params">data</span>)&#123;<br>	<span class="hljs-comment">// 插槽的内容</span><br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs">这说明 v-slot 的值实际上是任何能作为函数定义中的参数的JavaScript表达式<br></code></pre></td></tr></table></figure>
那么在子组件声明插槽的这句话中：<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&lt;slot name=<span class="hljs-string">&quot;slot1&quot;</span> :username=<span class="hljs-string">&quot;username&quot;</span> :age=<span class="hljs-string">&quot;age&quot;</span>&gt;&lt;/slot&gt;<br></code></pre></td></tr></table></figure>
Vue2底层做的工作：从当前的Vue组件里的data变量username和age，如果data中没有就从methods里查找，查找数据后，在填补该插槽的父组件调用时将获取到这个数据，比如在这里就应该是：<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&#123;<br>  <span class="hljs-attr">username</span>: <span class="hljs-string">&#x27;uni&#x27;</span>,<br>  <span class="hljs-attr">age</span>: <span class="hljs-string">&#x27;22&#x27;</span>,<br>&#125;<br></code></pre></td></tr></table></figure>
这是一个JS中的Object对象，而且里面的value已经是比较简单的字符串了，复杂的情况下可能value<br>会是一个函数，或者仍然是一个对象，层层嵌套。</li>
</ul>
<p>接下来就详细分析在上述案例中，在父组件填补插槽两种不同的情况下的发生的解构赋值：</p>
<p><strong>情况一：指定为整个对象（slot传参少的话可以使用）</strong></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span> #<span class="hljs-attr">slot1</span>=<span class="hljs-string">&quot;data&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>不同的方式输出slot的数据: &#123;&#123;data&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>直接获取对象的属性: &#123;&#123;data.username&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>直接获取对象的属性: &#123;&#123;data.age&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span> <br></code></pre></td></tr></table></figure>
<p><strong>运行效果：</strong><br><img src="https://img-blog.csdnimg.cn/492e38dd3f49484e84a744db605e1175.png#=50%x" srcset="/img/loading.gif" lazyload alt="在这里插入图片描述"></p>
<p>这里发生的解构是：基础解构</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 相当于</span><br><span class="hljs-keyword">let</span> data = &#123;<br>  <span class="hljs-attr">username</span>: <span class="hljs-string">&#x27;uni&#x27;</span>,<br>  <span class="hljs-attr">age</span>: <span class="hljs-string">&#x27;22&#x27;</span>,<br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>情况二：指定为对象（推荐使用）</strong></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span> #<span class="hljs-attr">slot1</span>=<span class="hljs-string">&quot;&#123;username, age, abc&#125;&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>不同的方式输出slot的数据: &#123;&#123;username&#125;&#125;, &#123;&#123;age&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>当获取不存在的参数时：&#123;&#123;typeof(abc)&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p><strong>运行效果：</strong><br>![在这里插入图片描述](<a target="_blank" rel="noopener" href="https://img-blog.csdnimg.cn/98d87338c47549f9a9a92463d0c58749.png#">https://img-blog.csdnimg.cn/98d87338c47549f9a9a92463d0c58749.png#</a> &#x3D;50%x)<br>这里发生的解构是：基础解构（和之前相同）</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 相当于</span><br><span class="hljs-keyword">let</span> &#123;username, age, abc&#125; = &#123;<br>  <span class="hljs-attr">username</span>: <span class="hljs-string">&#x27;uni&#x27;</span>,<br>  <span class="hljs-attr">age</span>: <span class="hljs-string">&#x27;22&#x27;</span>,<br>&#125;<br></code></pre></td></tr></table></figure>
<p>通过上面案例可以看到，如果{ } 里的参数值在子组件的slot标签里未指定，那么在父组件进行调用时候就默认为undefined类型。</p>
<p>我们可以通过下面的默认值解构来解决这个问题，就是当数据不存在时赋予一个默认值。</p>
<p><strong>解构的进阶：默认值解构</strong></p>
<p>假设将之前的HTML代码替换成如下：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span> #<span class="hljs-attr">slot1</span>=<span class="hljs-string">&quot;&#123;username, age, abc=&#x27;Vue666&#x27;&#125;&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>不同的方式输出slot的数据: &#123;&#123;username&#125;&#125;, &#123;&#123;age&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>当获取不存在的参数时，但设置了默认值时：&#123;&#123;abc&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p><strong>运行效果：</strong></p>
<p>![在这里插入图片描述](<a target="_blank" rel="noopener" href="https://img-blog.csdnimg.cn/0c6dfb2da24b45768f1ecb6f916a42b3.png#">https://img-blog.csdnimg.cn/0c6dfb2da24b45768f1ecb6f916a42b3.png#</a> &#x3D;50%x)<br>这里发生的解构是：默认值解构</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 相当于</span><br><span class="hljs-keyword">let</span> &#123;username, age, abc=<span class="hljs-string">&#x27;Vue666&#x27;</span>&#125; = &#123;<br>  <span class="hljs-attr">username</span>: <span class="hljs-string">&#x27;uni&#x27;</span>,<br>  <span class="hljs-attr">age</span>: <span class="hljs-string">&#x27;22&#x27;</span>,<br>&#125;<br></code></pre></td></tr></table></figure>
<p>综上，Vue2作用域插槽支持子组件向父组件传递参数，同时支持ES6的解构赋值。</p>
<h2 id="3-4-动态插槽名"><a href="#3-4-动态插槽名" class="headerlink" title="3.4 动态插槽名"></a>3.4 动态插槽名</h2><p><strong><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-slots.html#%E5%8A%A8%E6%80%81%E6%8F%92%E6%A7%BD%E5%90%8D">动态插槽名</a></strong> 是指 <a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/syntax.html#%E5%8A%A8%E6%80%81%E5%8F%82%E6%95%B0">动态指令参数</a>也可以用在 v-slot 上，来定义动态的插槽名：</p>
<p>使用语法：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">v-slot:</span>[<span class="hljs-attr">dynamicSlotName</span>]&gt;</span><br>  ...<br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p><strong>案例：</strong></p>
<ul>
<li>Header子组件:<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>头部<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;slot1&quot;</span> <span class="hljs-attr">:title</span>=<span class="hljs-string">&quot;&#x27;插槽1&#x27;&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;slot2&quot;</span> <span class="hljs-attr">:title</span>=<span class="hljs-string">&quot;&#x27;插槽2&#x27;&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span><br><span class="language-javascript">    <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;Header&#x27;</span>,</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure></li>
<li>App父组件：<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;app&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;slotType = &#x27;slot1&#x27;&quot;</span>&gt;</span>选择插槽1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;slotType = &#x27;slot2&#x27;&quot;</span>&gt;</span>选择插槽2<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">template</span> #[<span class="hljs-attr">slotType</span>]=<span class="hljs-string">&quot;title&quot;</span>&gt;</span><br>          当前选择的插槽为： &#123;&#123;title&#125;&#125;<br>      <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Header</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./components/Header.vue&#x27;</span></span><br><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span><br><span class="language-javascript">  <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;App&#x27;</span>,</span><br><span class="language-javascript">  <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>)&#123;</span><br><span class="language-javascript">    <span class="hljs-keyword">return</span> &#123;</span><br><span class="language-javascript">      <span class="hljs-attr">slotType</span>: <span class="hljs-string">&#x27;slot1&#x27;</span></span><br><span class="language-javascript">    &#125;</span><br><span class="language-javascript">  &#125;,</span><br><span class="language-javascript">  <span class="hljs-attr">components</span>: &#123;<span class="hljs-title class_">Header</span>&#125;</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure></li>
</ul>
<p>实现效果：</p>
<p>![在这里插入图片描述](<a target="_blank" rel="noopener" href="https://img-blog.csdnimg.cn/09e11fd1af3c4b3fa0fcab8485e7923d.gif#">https://img-blog.csdnimg.cn/09e11fd1af3c4b3fa0fcab8485e7923d.gif#</a> &#x3D;50%x)<br>如上图，动态插槽支持父组件在不同的场景下引入子组件的插槽。</p>
<h1 id="四、GitHub用户搜索案例"><a href="#四、GitHub用户搜索案例" class="headerlink" title="四、GitHub用户搜索案例"></a>四、GitHub用户搜索案例</h1><hr>
<p>做一个简单的搜索页面，用户输入用户名后，发送GET请求到GitHub提供的接口，获取对应用户名的列表信息（部分），最终列表信息将展示到页面上。</p>
<p>实现效果如下：</p>
<p><img src="https://img-blog.csdnimg.cn/9a7ae2f9da764283862164c893506192.gif#pic_center" srcset="/img/loading.gif" lazyload alt="在这里插入图片描述"></p>
<h2 id="4-1-准备静态的HTML文件"><a href="#4-1-准备静态的HTML文件" class="headerlink" title="4.1 准备静态的HTML文件"></a>4.1 准备静态的HTML文件</h2><p> <code>index.html </code></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">&quot;&quot;</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;utf-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">&quot;X-UA-Compatible&quot;</span> <span class="hljs-attr">content</span>=<span class="hljs-string">&quot;IE=edge&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;viewport&quot;</span> <span class="hljs-attr">content</span>=<span class="hljs-string">&quot;width=device-width,initial-scale=1.0&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">&quot;icon&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;&lt;%= BASE_URL %&gt;favicon.ico&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Bootstrap 样式--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css&quot;</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">&quot;stylesheet&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>&lt;%= htmlWebpackPlugin.options.title %&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">noscript</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span> 浏览器不支持JavaScript. <span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">noscript</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;text-center&quot;</span>&gt;</span>基于Vue2的GitHub用户搜索案例<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- Container Begin--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;container shadow&quot;</span>&gt;</span><br>        <span class="hljs-comment">&lt;!--Head 搜索栏 Begin--&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;mb-3 row&quot;</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">&quot;input-search&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;col-sm-2 col-form-label text-end&quot;</span>&gt;</span>搜索GitHub用户<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;col-sm-8&quot;</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;form-control&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;input-search&quot;</span>&gt;</span><br>          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;col-sm-2&quot;</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;btn btn-primary&quot;</span>&gt;</span>搜索<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>        <span class="hljs-comment">&lt;!--Head 搜索栏 End --&gt;</span><br><br>        <span class="hljs-comment">&lt;!--Body GitHub用户列表 Begin --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;container&quot;</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;list-unstyled row row-cols-md-4 &quot;</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;mb-5&quot;</span>&gt;</span><br>              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card text-center mx-auto&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 120px;&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>                  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;logo.png&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-img-top mx-auto shadow&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 100px;height: 100px;border-radius: 50%;&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-body&quot;</span>&gt;</span><br>                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-text text-success&quot;</span>&gt;</span> 用户名 <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;mb-5&quot;</span>&gt;</span><br>              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card text-center mx-auto&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 120px;&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>                  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;logo.png&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-img-top mx-auto shadow&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 100px;height: 100px;border-radius: 50%;&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-body&quot;</span>&gt;</span><br>                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-text text-success&quot;</span>&gt;</span> 用户名 <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;mb-5&quot;</span>&gt;</span><br>              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card text-center mx-auto&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 120px;&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>                  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;logo.png&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-img-top mx-auto shadow&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 100px;height: 100px;border-radius: 50%;&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-body&quot;</span>&gt;</span><br>                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-text text-success&quot;</span>&gt;</span> 用户名 <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;mb-5&quot;</span>&gt;</span><br>              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card text-center mx-auto&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 120px;&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>                  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;logo.png&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-img-top mx-auto shadow&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 100px;height: 100px;border-radius: 50%;&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-body&quot;</span>&gt;</span><br>                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-text text-success&quot;</span>&gt;</span> 用户名 <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>          <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>      <span class="hljs-comment">&lt;!--Body GitHub用户列表 End--&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- Container End --&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- Vue2 App 组件入口 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;app&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br><br></code></pre></td></tr></table></figure>

<p><strong>运行效果：</strong></p>
<p><img src="https://img-blog.csdnimg.cn/3fa4d9ce58da4d038f3db1aedffb540a.png" srcset="/img/loading.gif" lazyload alt="在这里插入图片描述"></p>
<h2 id="4-2-根据静态文件划分组件"><a href="#4-2-根据静态文件划分组件" class="headerlink" title="4.2 根据静态文件划分组件"></a>4.2 根据静态文件划分组件</h2><p>除了管理主页面的App组件以外，该页面内部分为Header搜索和Body用户列表显示<br><img src="https://img-blog.csdnimg.cn/a12456f304634e3098ffa278e7195fc1.png" srcset="/img/loading.gif" lazyload alt="在这里插入图片描述"></p>
<h2 id="4-3-代码实现"><a href="#4-3-代码实现" class="headerlink" title="4.3 代码实现"></a>4.3 代码实现</h2><h3 id="index-html"><a href="#index-html" class="headerlink" title="index.html"></a>index.html</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">&quot;&quot;</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;utf-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">&quot;X-UA-Compatible&quot;</span> <span class="hljs-attr">content</span>=<span class="hljs-string">&quot;IE=edge&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;viewport&quot;</span> <span class="hljs-attr">content</span>=<span class="hljs-string">&quot;width=device-width,initial-scale=1.0&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">&quot;icon&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;&lt;%= BASE_URL %&gt;favicon.ico&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Bootstrap 样式--&gt;</span><br>    <span class="hljs-comment">&lt;!-- &lt;link href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css&quot; rel=&quot;stylesheet&quot;&gt; --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>&lt;%= htmlWebpackPlugin.options.title %&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">noscript</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span> 浏览器不支持JavaScript. <span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">noscript</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;text-center&quot;</span>&gt;</span>基于Vue2的GitHub用户搜索案例<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- Vue2 App 组件入口 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;app&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br><br></code></pre></td></tr></table></figure>

<h3 id="Main-js"><a href="#Main-js" class="headerlink" title="Main.js"></a>Main.js</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Vue</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;vue&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./App.vue&#x27;</span><br><br><span class="hljs-title class_">Vue</span>.<span class="hljs-property">config</span>.<span class="hljs-property">productionTip</span> = <span class="hljs-literal">false</span><br><span class="hljs-keyword">import</span> vueResource <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;vue-resource&#x27;</span><br><span class="hljs-comment">//npm i vue-resource</span><br><span class="hljs-comment">//使用插件vue-resource 发送GET请求</span><br><span class="hljs-title class_">Vue</span>.<span class="hljs-title function_">use</span>(vueResource)<br><span class="hljs-keyword">new</span> <span class="hljs-title class_">Vue</span>(&#123;<br>  <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#app&#x27;</span>,<br>  <span class="hljs-attr">render</span>: <span class="hljs-function"><span class="hljs-params">h</span> =&gt;</span> <span class="hljs-title function_">h</span>(<span class="hljs-title class_">App</span>),<br>  <span class="hljs-title function_">beforeCreate</span>(<span class="hljs-params"></span>)&#123;<br>    <span class="hljs-title class_">Vue</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">$bus</span> = <span class="hljs-variable language_">this</span><br>  &#125;<br>&#125;)<br></code></pre></td></tr></table></figure>
<h3 id="App-vue"><a href="#App-vue" class="headerlink" title="App.vue"></a>App.vue</h3><p>组件通信采用和上回一样的全局事件总线：</p>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/Unirithe/article/details/125390549">Vue学习笔记（二）基于Vue2的TodoList待办事项案例 | localStorage本地存储 | Vue2的发布与订阅 | Vue2支持的动画类 |JavaScript原型对象</a></p>
<p>这里主要是自定义的Header和自定义的Body两个组件的数据通信，Header负责搜索GitHub的用户信息，发送出去，而Body则负责接收（订阅）用户的列表数据。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-comment">&lt;!-- Container Begin--&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;container shadow&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!--Head 搜索栏 Begin--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">Header</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">Header</span>&gt;</span><br>    <span class="hljs-comment">&lt;!--Head 搜索栏 End --&gt;</span><br><br>    <span class="hljs-comment">&lt;!--Body GitHub用户列表 Begin --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">Body</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">Body</span>&gt;</span><br>     <span class="hljs-comment">&lt;!--Body GitHub用户列表 End--&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>  <span class="hljs-comment">&lt;!-- Container End --&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-comment">// npm i bootstrap</span></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">&#x27;bootstrap/dist/js/bootstrap&#x27;</span></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">&#x27;bootstrap/dist/css/bootstrap.min.css&#x27;</span></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Header</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./components/GitHubHeader.vue&#x27;</span></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Body</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./components/GitHubBody.vue&#x27;</span></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span><br><span class="language-javascript">  <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;App&#x27;</span>,</span><br><span class="language-javascript">  <span class="hljs-attr">components</span>: &#123;<span class="hljs-title class_">Header</span>, <span class="hljs-title class_">Body</span>&#125;,</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<h3 id="GitHubHeader-vue-基于axios发送AJAX请求"><a href="#GitHubHeader-vue-基于axios发送AJAX请求" class="headerlink" title="GitHubHeader.vue 基于axios发送AJAX请求"></a>GitHubHeader.vue 基于axios发送AJAX请求</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;mb-3 row&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">&quot;input-search&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;col-sm-2 col-form-label text-end&quot;</span>&gt;</span>搜索GitHub用户<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;col-sm-8&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;form-control&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;input-search&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;searchName&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;col-sm-2&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;btn btn-primary&quot;</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;search()&quot;</span>&gt;</span>搜索<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;axios&#x27;</span></span><br><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span><br><span class="language-javascript">    <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;Header&#x27;</span>,</span><br><span class="language-javascript">    <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>)&#123;</span><br><span class="language-javascript">        <span class="hljs-keyword">return</span> &#123;</span><br><span class="language-javascript">            <span class="hljs-attr">searchName</span>: <span class="hljs-string">&#x27;&#x27;</span></span><br><span class="language-javascript">        &#125;</span><br><span class="language-javascript">    &#125;,</span><br><span class="language-javascript">    <span class="hljs-attr">methods</span>: &#123;</span><br><span class="language-javascript">        <span class="hljs-title function_">search</span>(<span class="hljs-params"></span>)&#123;</span><br><span class="language-javascript">            <span class="hljs-comment">// 防止用户输入空的名称</span></span><br><span class="language-javascript">            <span class="hljs-keyword">if</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">searchName</span> === <span class="hljs-string">&#x27;&#x27;</span>) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$emit(</span><br><span class="language-javascript">                <span class="hljs-string">&#x27;selectUserByName&#x27;</span>, &#123;<span class="hljs-attr">isFirst</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">errorMsg</span>: <span class="hljs-string">&#x27;无法查询空的名称&#x27;</span>&#125;</span><br><span class="language-javascript">            )</span><br><span class="language-javascript">            <span class="hljs-comment">// 发布加载的消息</span></span><br><span class="language-javascript">            <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$emit(<span class="hljs-string">&#x27;selectUserByName&#x27;</span>, &#123;<span class="hljs-attr">errorMsg</span>: <span class="hljs-string">&#x27;&#x27;</span>, <span class="hljs-attr">isFirst</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">isLoading</span>: <span class="hljs-literal">true</span>&#125;)</span><br><span class="language-javascript"></span><br><span class="language-javascript">            <span class="hljs-comment">// 方式一: 使用 axios</span></span><br><span class="language-javascript">            <span class="hljs-comment">/*</span></span><br><span class="hljs-comment"><span class="language-javascript">            axios.get(`https://api.github.com/search/users?q=$&#123;this.searchName&#125;`).then(</span></span><br><span class="hljs-comment"><span class="language-javascript">                response =&gt; &#123;</span></span><br><span class="hljs-comment"><span class="language-javascript">                    console.log(&#x27;请求成功&#x27;)</span></span><br><span class="hljs-comment"><span class="language-javascript">                    // 发布请求成功的消息</span></span><br><span class="hljs-comment"><span class="language-javascript">                    this.$bus.$emit(&#x27;selectUserByName&#x27;, &#123;</span></span><br><span class="hljs-comment"><span class="language-javascript">                        errorMsg: &#x27;&#x27;,</span></span><br><span class="hljs-comment"><span class="language-javascript">                        isLoading: false,</span></span><br><span class="hljs-comment"><span class="language-javascript">                        userList: response.data.items,</span></span><br><span class="hljs-comment"><span class="language-javascript">                    &#125;)</span></span><br><span class="hljs-comment"><span class="language-javascript">                &#125;,</span></span><br><span class="hljs-comment"><span class="language-javascript">                error =&gt; &#123;</span></span><br><span class="hljs-comment"><span class="language-javascript">                    console.log(&#x27;请求失败&#x27;, error.message)</span></span><br><span class="hljs-comment"><span class="language-javascript">                    // 发布请求失败的消息</span></span><br><span class="hljs-comment"><span class="language-javascript">                    this.$bus.$emit(&#x27;selectUserByName&#x27;, &#123;</span></span><br><span class="hljs-comment"><span class="language-javascript">                        isLoading: false,</span></span><br><span class="hljs-comment"><span class="language-javascript">                        errorMsg: &#x27;获取数据失败&#x27;</span></span><br><span class="hljs-comment"><span class="language-javascript">                    &#125;)</span></span><br><span class="hljs-comment"><span class="language-javascript">                &#125;</span></span><br><span class="hljs-comment"><span class="language-javascript">            )</span></span><br><span class="hljs-comment"><span class="language-javascript">            */</span></span><br><span class="language-javascript">            <span class="hljs-comment">// 方式二: 使用 vue-resource</span></span><br><span class="language-javascript">            <span class="hljs-variable language_">this</span>.<span class="hljs-property">$http</span>.<span class="hljs-title function_">get</span>(<span class="hljs-string">`https://api.github.com/search/users?q=<span class="hljs-subst">$&#123;<span class="hljs-variable language_">this</span>.searchName&#125;</span>`</span>).<span class="hljs-title function_">then</span>(</span><br><span class="language-javascript">                <span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> &#123;</span><br><span class="language-javascript">                    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;请求成功&#x27;</span>)</span><br><span class="language-javascript">                    <span class="hljs-comment">// 发布请求成功的消息</span></span><br><span class="language-javascript">                    <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$emit(<span class="hljs-string">&#x27;selectUserByName&#x27;</span>, &#123;</span><br><span class="language-javascript">                        <span class="hljs-attr">errorMsg</span>: <span class="hljs-string">&#x27;&#x27;</span>,</span><br><span class="language-javascript">                        <span class="hljs-attr">isLoading</span>: <span class="hljs-literal">false</span>,</span><br><span class="language-javascript">                        <span class="hljs-attr">userList</span>: response.<span class="hljs-property">data</span>.<span class="hljs-property">items</span>,</span><br><span class="language-javascript">                    &#125;)</span><br><span class="language-javascript">                &#125;,</span><br><span class="language-javascript">                <span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> &#123;</span><br><span class="language-javascript">                    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;请求失败&#x27;</span>, error.<span class="hljs-property">message</span>)</span><br><span class="language-javascript">                    <span class="hljs-comment">// 发布请求失败的消息</span></span><br><span class="language-javascript">                    <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$emit(<span class="hljs-string">&#x27;selectUserByName&#x27;</span>, &#123;</span><br><span class="language-javascript">                        <span class="hljs-attr">isLoading</span>: <span class="hljs-literal">false</span>,</span><br><span class="language-javascript">                        <span class="hljs-attr">errorMsg</span>: <span class="hljs-string">&#x27;获取数据失败&#x27;</span></span><br><span class="language-javascript">                    &#125;)</span><br><span class="language-javascript">                &#125;</span><br><span class="language-javascript">            )</span><br><span class="language-javascript">        &#125;</span><br><span class="language-javascript">    &#125;,</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<h3 id="GitHubBody-vue"><a href="#GitHubBody-vue" class="headerlink" title="GitHubBody.vue"></a>GitHubBody.vue</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>   <br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;container&quot;</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- 欢迎提示 --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">&quot;info.isFirst&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;text-center&quot;</span>&gt;</span>❤ 欢迎访问 ❤ <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- 错误提示 --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">&quot;info.errorMsg&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;text-center text-danger&quot;</span>&gt;</span>错误: &#123;&#123; info.errorMsg &#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- 加载页面 --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">&quot;info.isLoading&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;d-flex justify-content-center&quot;</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">&quot;info.isLoading&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;spinner-border text-info&quot;</span> <span class="hljs-attr">role</span>=<span class="hljs-string">&quot;status&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;visually-hidden&quot;</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- 用户列表 --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h5</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">&quot;info.userList.length&quot;</span> &gt;</span>共 &#123;&#123;info.userList.length&#125;&#125; 条结果<span class="hljs-tag">&lt;/<span class="hljs-name">h5</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">&quot;info.userList.length&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;list-unstyled row row-cols-md-4 &quot;</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;mb-5&quot;</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(user) in info.userList&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;user.name&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card text-center mx-auto&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 120px;&quot;</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>                    <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">:href</span>=<span class="hljs-string">&quot;user.html_url&quot;</span> <span class="hljs-attr">target</span>=<span class="hljs-string">&quot;_blank&quot;</span>&gt;</span><br>                        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">:src</span>=<span class="hljs-string">&quot;user.avatar_url&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-img-top mx-auto shadow&quot;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;width: 100px;height: 100px;border-radius: 50%;&quot;</span>&gt;</span><br>                    <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-body&quot;</span>&gt;</span><br>                    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;card-text text-success&quot;</span>&gt;</span> &#123;&#123; user.login &#125;&#125; <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>     <br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript"></span><br><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span><br><span class="language-javascript">    <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;Body&#x27;</span>,</span><br><span class="language-javascript">    <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>)&#123;</span><br><span class="language-javascript">        <span class="hljs-keyword">return</span> &#123;</span><br><span class="language-javascript">            <span class="hljs-attr">info</span>:&#123;</span><br><span class="language-javascript">                <span class="hljs-attr">isFirst</span>: <span class="hljs-literal">true</span>,      <span class="hljs-comment">// 初次访问时, 默认为true</span></span><br><span class="language-javascript">                <span class="hljs-attr">isLoading</span>: <span class="hljs-literal">false</span>,  <span class="hljs-comment">// 加载标记</span></span><br><span class="language-javascript">                <span class="hljs-attr">errorMsg</span>: <span class="hljs-string">&#x27;&#x27;</span>,      <span class="hljs-comment">// 错误信息</span></span><br><span class="language-javascript">                <span class="hljs-attr">userList</span>:[]        <span class="hljs-comment">// 用户数据</span></span><br><span class="language-javascript">            &#125;</span><br><span class="language-javascript">        &#125;</span><br><span class="language-javascript">    &#125;,</span><br><span class="language-javascript">    <span class="hljs-attr">methods</span>: &#123;</span><br><span class="language-javascript"></span><br><span class="language-javascript">    &#125;,</span><br><span class="language-javascript">    <span class="hljs-title function_">mounted</span>(<span class="hljs-params"></span>)&#123;</span><br><span class="language-javascript">        <span class="hljs-comment">// 订阅（合并参数）</span></span><br><span class="language-javascript">        <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$on(<span class="hljs-string">&#x27;selectUserByName&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">newInfo</span>)=&gt;</span>&#123;</span><br><span class="language-javascript">            <span class="hljs-variable language_">this</span>.<span class="hljs-property">info</span> = &#123;...<span class="hljs-variable language_">this</span>.<span class="hljs-property">info</span>, ...newInfo&#125;</span><br><span class="language-javascript">        &#125;)</span><br><span class="language-javascript">    &#125;,</span><br><span class="language-javascript">    <span class="hljs-title function_">beforeDestroy</span>(<span class="hljs-params"></span>)&#123;</span><br><span class="language-javascript">        <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$off(<span class="hljs-string">&#x27;selectUserByName&#x27;</span>)</span><br><span class="language-javascript">    &#125;</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<h1 id="五、浏览器跨域"><a href="#五、浏览器跨域" class="headerlink" title="五、浏览器跨域"></a>五、浏览器跨域</h1><p><strong>参考文献</strong> </p>
<p>[1] <a target="_blank" rel="noopener" href="https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=CJFD&dbname=CJFD2014&filename=DNBC201408041">周晓黎.Ajax跨域访问Web Services[J].电脑编程技巧与维护,2014(08):93-96.DOI:10.16184&#x2F;j.cnki.comprg.2014.08.058.</a><br>[2] <a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/159060398">详解浏览器跨域的几种方法</a></p>
<h2 id="5-1-什么是浏览器跨域"><a href="#5-1-什么是浏览器跨域" class="headerlink" title="5.1 什么是浏览器跨域"></a>5.1 什么是浏览器跨域</h2><p>在WEB前端开发中，最常见的跨域问题就是浏览器在A域名页面发送B域名的请求时会被限制。</p>
<p>这种跨域往往来自对URL的GET请求或者是JavaScript通过AJAX发送的GET、POST等请求。</p>
<blockquote>
<p>AJAX是 Asynchronus JavaScript and XML（异步JavaScript和XML）的缩写，AJAX主要运用了XMLHttpRequest，即异步数据读取技术，从而可以自主的发起Web请求，与远程服务器进行数据交互。[1]</p>
</blockquote>
<p>在Vue中，通常使用axios发送异步请求，而不是AJAX。</p>
<blockquote>
<p>axios技术是基于JS的 <a target="_blank" rel="noopener" href="https://www.runoob.com/js/js-promise.html"><strong>Promise</strong></a> 实现的，<strong>Promise</strong> 是一个 ECMAScript 6 提供的类，目的是更加优雅地书写复杂的异步任务，所以 axios与ajax的最大区别就是，axios支持Promise中的API，所以在Vue技术中，axios是发送请求的主流技术。</p>
</blockquote>
<p>而axios和ajax本质上都是向某个URL发送请求，接下来将以AJAX的角度来描述跨域问题。</p>
<p>传统Web应用程序和Ajax方式的Web应用程序交互方式的比较如下图所示：<br>![在这里插入图片描述](<a target="_blank" rel="noopener" href="https://img-blog.csdnimg.cn/29835ed074af4ec89d43860cd5056efb.png#pic_center">https://img-blog.csdnimg.cn/29835ed074af4ec89d43860cd5056efb.png#pic_center</a> &#x3D;60%x)</p>
<blockquote>
<p>从图中可以看出，使用AJAX技术可以减少用户在前端页面等待的时间，提升用户的体验。<br>使用AJAX技术构建的Web页面，无需终端交互流程即可重新加载和动态更新。[1]</p>
</blockquote>
<p>当使用AJAX向服务器请求资源时，此时就会涉及安全问题，在常见的JavaWeb开发中，通常是通过Tomcat部署Web项目，如果是在本地部署的话，就不会出现这个问题：</p>
<p>比如在 <code>login.html</code> 登录页面中，点击登录后需要向服务器发送登录请求，比如是向 <code>/user/login</code> 发送请求，为什么这时我们可以直接访问到服务器呢？其实不难理解，毕竟是在同一台机器上，那么肯定不会出现权限问题。</p>
<p>其实在Web浏览器中，有这么一个规则限制了JavaScript脚本代码的访问权限，并不是说想对哪个服务器发送请求，服务器就会接受，通常JS的限制有两种。第一种是对客户端的操作权限进行限制，第二个是对远程操作进行限制。</p>
<p><strong>JS操作客户端的限制</strong></p>
<p>1）不允许写本地文件和目录<br>2）不允许删除本地文件和目录</p>
<p>说白了就是操作本地文件和目录的话只能进行读取，最常见的就是设置头像，比如我们可以在CSDN网站的个人中心里修改自己的头像，修改头像操作本质上就是通过JavaScript代码来读取我们电脑的本地文件，但是我们不能在网站里面修改自己电脑上的文件，这是不允许的，否则当我们进了一个恶意篡改的网站，万一允许的话，自己电脑的文件就会被修改或者被删除，那么就会出现很严重的问题。</p>
<p><strong>JS远程操作的限制</strong></p>
<p>JavaScript 脚本代码对远程服务器的操作限制称为 <strong>同源策略（Same-Origin Policy）</strong>，即 JS脚本只能访问与包含它的文档在同一域（domain）下的文档。</p>
<p>什么是域呢？</p>
<p>首先一个远程网页的URL由四个部分组成： <code>协议://主机:端口号/路径 </code>，比如：<code>http://localhost:8080</code>（此时路径为 <code>/</code>）</p>
<p>同一域就是指两个URL的 <code>协议://主机:端口</code> 这3个部分相同的情况。</p>
<p>HTTP协议的默认端口号为80，HTTPS协议的默认端口号为443，因为是国际统一的标准，我们在访问网页时，这两个端口号不会显示出来，而我们自己在部署Web项目时，则可以指定为其他的端口号，比如8080、8081、80等，接下来以最常见的 <code>http://localhsot:8080</code> 这个URL为例，与它同源或需跨域的各种URL样式如下（这里默认本地主机名的DNS域名配置的主机名与IP不同）：</p>
<table>
<thead>
<tr>
<th align="left">JS访问的URL</th>
<th align="left">访问方式</th>
<th align="left">原因</th>
</tr>
</thead>
<tbody><tr>
<td align="left"><a target="_blank" rel="noopener" href="http://localhost:8080/user/login">http://localhost:8080/user/login</a></td>
<td align="left">同源</td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a target="_blank" rel="noopener" href="http://localhost:8080/index">http://localhost:8080/index</a></td>
<td align="left">同源</td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a target="_blank" rel="noopener" href="http://uni:8080/">http://uni:8080</a></td>
<td align="left">跨域</td>
<td align="left">主机不同</td>
</tr>
<tr>
<td align="left"><a target="_blank" rel="noopener" href="http://localhost/">http://localhost:80</a></td>
<td align="left">跨域</td>
<td align="left">端口不同</td>
</tr>
<tr>
<td align="left"><a target="_blank" rel="noopener" href="https://localhost:8080/">https://localhost:8080</a></td>
<td align="left">跨域</td>
<td align="left">协议不同</td>
</tr>
</tbody></table>
<p>根据 [2] 中提出的例子：</p>
<blockquote>
<p>A 网站是一家银行网站，A网站在用户的机器上设置了一个Cookie，包含一些隐私信息（比如存款总额），当用户离开A网站后，又去访问B网站，如果没有同源限制，那么B网站就可以读取A网站的Cookie，那么隐私信息就会泄露。更可怕的是，有的网站会使用Cookie来保存用户的登录状态，如果用户没有退出登录，其他网站就可以冒充用户，为所欲为。</p>
</blockquote>
<p>在Web前端非同源情况下，共有三个行为受到限制：</p>
<ul>
<li>Cookie、LocalStorage和IndexDB 无法读取</li>
<li>DOM无法获得</li>
<li>AJAX请求不能发送</li>
</ul>
<p>正因为有这个限制，当我们访问不同的网站时，用浏览器调试工具去查看Cookie、localStorage、IndexDB这些信息，显示出来的结果也是不一样的，虽然都是保存在我们本地机器上，但是不同的网站只能从我们的机器上读取各自的信息，而不能读取其他网站保存到我们机器上的信息。</p>
<p><strong>通过一个案例来查看跨域问题：</strong></p>
<p>后端SpringBoot 提供一个接口，&#x2F;hello，该接口返回简单的JSON数据，格式如下：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&#123;<br>	<span class="hljs-attr">code</span>: <span class="hljs-string">&#x27;200&#x27;</span>,<br>	<span class="hljs-attr">msg</span>: <span class="hljs-string">&#x27;你好呀!&#x27;</span><br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>Controller层代码：</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">package</span> com.uni.crossdomain.controller;<br><br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.GetMapping;<br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RestController;<br><br><span class="hljs-keyword">import</span> java.util.HashMap;<br><span class="hljs-keyword">import</span> java.util.Map;<br><br><span class="hljs-meta">@RestController</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">UserController</span> &#123;<br>    <span class="hljs-meta">@GetMapping(&quot;/hello&quot;)</span><br>    <span class="hljs-keyword">public</span> Map&lt;String, Object&gt; <span class="hljs-title function_">hello</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;String, Object&gt;()&#123;&#123;<br>            put(<span class="hljs-string">&quot;code&quot;</span>, <span class="hljs-number">200</span>);<br>            put(<span class="hljs-string">&quot;msg&quot;</span>, <span class="hljs-string">&quot;你好呀!&quot;</span>);<br>        &#125;&#125;;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>运行效果：</strong></p>
<p>![在这里插入图片描述](<a target="_blank" rel="noopener" href="https://img-blog.csdnimg.cn/154468849b9c41d3b0a0f24b0bb58562.png#">https://img-blog.csdnimg.cn/154468849b9c41d3b0a0f24b0bb58562.png#</a> &#x3D;50%x)<br>接下来，使用vscode编辑HTML页面，使用 <code>Live Server </code>插件部署一个端口号为5000的前端项目</p>
<p>HTML代码如下（使用JQuery实现AJAX请求）：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">&quot;en&quot;</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>跨域测试<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>待发送请求<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">&quot;get(this)&quot;</span>&gt;</span>点击向 http://localhost:8080/hello 发送AJAX请求<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript">        <span class="hljs-keyword">function</span> <span class="hljs-title function_">get</span>(<span class="hljs-params">btn</span>)&#123;</span><br><span class="language-javascript">            $.<span class="hljs-title function_">ajax</span>(&#123;</span><br><span class="language-javascript">                <span class="hljs-attr">url</span>: <span class="hljs-string">&#x27;http://localhost:8080/hello&#x27;</span>,</span><br><span class="language-javascript">                <span class="hljs-attr">type</span>: <span class="hljs-string">&#x27;GET&#x27;</span>,</span><br><span class="language-javascript">                <span class="hljs-attr">error</span>: <span class="hljs-function">(<span class="hljs-params">errMsg</span>) =&gt;</span>&#123;</span><br><span class="language-javascript">                    <span class="hljs-title function_">alert</span>(<span class="hljs-string">&#x27;请求失败&#x27;</span>)</span><br><span class="language-javascript">                    $(btn).<span class="hljs-title function_">prev</span>().<span class="hljs-title function_">text</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(errMsg))</span><br><span class="language-javascript">                &#125;,</span><br><span class="language-javascript">                <span class="hljs-attr">success</span>: <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span>&#123;</span><br><span class="language-javascript">                    <span class="hljs-title function_">alert</span>(<span class="hljs-string">&#x27;请求成功&#x27;</span>)</span><br><span class="language-javascript">                    $(btn).<span class="hljs-title function_">prev</span>().<span class="hljs-title function_">text</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(data))</span><br><span class="language-javascript">                &#125;</span><br><span class="language-javascript">            &#125;)</span><br><span class="language-javascript">        &#125;</span><br><span class="language-javascript">    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://img-blog.csdnimg.cn/25b0e3c779ac481688dee7f22291b963.png" srcset="/img/loading.gif" lazyload alt="在这里插入图片描述"><br>此时后端没有收到任何信息，AJAX返回的错误信息为：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&#123;<br>	<span class="hljs-string">&quot;readyState&quot;</span>:<span class="hljs-number">0</span><br>	<span class="hljs-string">&quot;status&quot;</span>:<span class="hljs-number">0</span>,<br>	<span class="hljs-string">&quot;statusText&quot;</span>:<span class="hljs-string">&quot;error&quot;</span><br>&#125;<br></code></pre></td></tr></table></figure>
<p>浏览器报错的信息为：</p>
<p>Access to XMLHttpRequest at ‘<a target="_blank" rel="noopener" href="http://localhost:8080/hello&#39;">http://localhost:8080/hello&#39;</a> from origin ‘<a href="http://127.0.0.1:5500&#39;">http://127.0.0.1:5500&#39;</a> has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.</p>
<p><strong>翻译后：</strong></p>
<p>访问位于’<a target="_blank" rel="noopener" href="http://localhost:8080/hello&#39;%E4%BB%8E%E5%8E%9F%E7%82%B9&#39;http://127.0.0.1:5500%E2%80%9C%E2%80%9D%E5%B7%B2%E8%A2%ABCORS%E7%AD%96%E7%95%A5%E9%98%BB%E6%AD%A2%EF%BC%9A%E8%AF%B7%E6%B1%82%E7%9A%84%E8%B5%84%E6%BA%90%E4%B8%8A%E4%B8%8D%E5%AD%98%E5%9C%A8%E2%80%9CAccess">http://localhost:8080/hello&#39;从原点&#39;http://127.0.0.1:5500“”已被CORS策略阻止：请求的资源上不存在“Access</a> Control Allow Origin”标头。</p>
<p>可以看到，由于我用5500的端口号去请求8080的端口号的资源，这里就被CORS策略拦截了，不过这里的localhost和127.0.0.1，即请求的主机是一样的，因为在本机的DNS域名配置文件（默认在C:\Windows\System32\drivers\etc\hosts）中有这么一段注释，即localhost本质上就是127.0.0.1的地址。</p>
<figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-comment"># localhost name resolution is handled within DNS itself.</span><br><span class="hljs-comment">#	127.0.0.1       localhost</span><br><span class="hljs-comment">#	::1             localhost</span><br></code></pre></td></tr></table></figure>

<h2 id="5-2-浏览器跨域的解决方案"><a href="#5-2-浏览器跨域的解决方案" class="headerlink" title="5.2 浏览器跨域的解决方案"></a>5.2 浏览器跨域的解决方案</h2><h3 id="CORS标准"><a href="#CORS标准" class="headerlink" title="CORS标准"></a>CORS标准</h3><blockquote>
<p>CORS 是一个 W3C 标准，全称是跨域资源共享（CORSs-origin resource sharing），它允许浏览器向跨源服务器，发出 <strong>XMLHttpRequest</strong> 请求。<br>其实，准确的来说，跨域机制是阻止了数据的跨域获取，不是阻止请求发送。<br>CORS需要浏览器和服务器同时支持。目前，所有浏览器都支持该功能，IE浏览器不能低于IE10。[2]</p>
</blockquote>
<blockquote>
<p>整个CORS通信过程，都是浏览器自动完成，不需要用户参与。对于开发者来说，CORS通信与同源的AJAX通信没有差别，代码完全一样。浏览器一旦发现AJAX请求跨源，就会自动添加一些附加的头信息，有时还会多出一次附加的请求，但用户不会有感觉。[2]</p>
</blockquote>
<p>因此，实现CORS通信的关键是服务器。只要服务器实现了CORS接口，就可以跨域通信。更多相关内容可以参考文章 <a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/159060398">点击查看</a>，这里主要是做个了解。</p>
<h3 id="JSONP跨域"><a href="#JSONP跨域" class="headerlink" title="JSONP跨域"></a>JSONP跨域</h3><p>在HTML文档中，通常会引入JS的脚本例如：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><br>    ... 自定义JS脚本<br><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>
<p>浏览器在加载HTML文档时，会顺序加载script标签中src的地址，这种加载是可以跨域加载的，浏览器不会阻止跨域的js加载。</p>
<p>比如在上个案例中</p>
<p>从本地的 <a target="_blank" rel="noopener" href="http://127.0.0.1:5000/">http://127.0.0.1:5000</a> 向 <a target="_blank" rel="noopener" href="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js</a>  请求获取到了JS脚本资源，这样一来，自定义的JS脚本里就可以使用JQuery的函数了，这就是一种跨域访问资源的真实案例。</p>
<p>此外，还有img等标签，可以跨域加载，比如我们可以在自己的网站中引入网络上的图片。</p>
<p>而 JSONP正是利用了script&#x2F;img等标签能够跨域加载，来实现跨域请求的功能，例如：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">showData</span>(<span class="hljs-params">data</span>)&#123;<br>	<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(data);<br>&#125;<br>$(<span class="hljs-string">&#x27;body&#x27;</span>).<span class="hljs-title function_">append</span>(<span class="hljs-string">`&lt;script src=&#x27;http://localhost:8080/hello?callback=showData&#x27;&gt;&lt;\/script&gt;`</span>);<br></code></pre></td></tr></table></figure>
<p><strong>测试结果：</strong></p>
<p>跨源读取阻止(CORB)功能阻止了 MIME 类型为 application&#x2F;json 的跨源响应<a target="_blank" rel="noopener" href="http://localhost:8080/hello?callback=showData&amp;_=1655954732590%E3%80%82%E6%9C%89%E5%85%B3%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AF%EF%BC%8C%E8%AF%B7%E5%8F%82%E9%98%85">http://localhost:8080/hello?callback=showData&amp;_=1655954732590。有关详细信息，请参阅</a> <a target="_blank" rel="noopener" href="https://www.chromestatus.com/feature/5629709824032768%E3%80%82">https://www.chromestatus.com/feature/5629709824032768。</a></p>
<p>仍然失败，这是因为服务端没有支持CORB跨域，这个BUG将在下面使用Vue2支持的代理服务器解决。</p>
<h3 id="代理服务器跨域-【Vue采取的策略】"><a href="#代理服务器跨域-【Vue采取的策略】" class="headerlink" title="代理服务器跨域 【Vue采取的策略】"></a>代理服务器跨域 【Vue采取的策略】</h3><p><a target="_blank" rel="noopener" href="https://cloud.tencent.com/developer/article/1427219">参考文章：通俗易懂的Nginx工作原理</a></p>
<p>提到 proxy反向代理不得不说一说 Nginx这个目前非常流行的框架。</p>
<p>Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器，同时也提供了IMAP&#x2F;POP3&#x2F;SMTP服务。</p>
<p>Ngnix的优点有很多：模块化、异步、多进程单线程等，除此之外，它解决了Ajax跨域的问题。</p>
<p>![在这里插入图片描述](<a target="_blank" rel="noopener" href="https://img-blog.csdnimg.cn/23c44f83a86946d58e86fead85865163.png#pic_center">https://img-blog.csdnimg.cn/23c44f83a86946d58e86fead85865163.png#pic_center</a> &#x3D;60%x)</p>
<p>大概了解这么一个解决跨域方式后，我们来熟悉一下Vue2中配置跨域的流程。</p>
<p>核心的配置：<a target="_blank" rel="noopener" href="https://cli.vuejs.org/zh/config/#devserver-proxy"><strong>devServer.proxy</strong></a></p>
<p><strong>Type: string | Object</strong></p>
<blockquote>
<p>如果你的前端应用和后端 API 服务器没有运行在同一个主机上，你需要在开发环境下将 API 请求代理到 API 服务器。这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。</p>
</blockquote>
<p><strong>案例：同样是之前的 5.1 部分提到的跨域案例。</strong></p>
<p>SpringBoot后端，端口号为8080，Controller层为：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">package</span> com.uni.crossdomain.controller;<br><br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.GetMapping;<br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestBody;<br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.ResponseBody;<br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RestController;<br><br><span class="hljs-keyword">import</span> java.util.HashMap;<br><span class="hljs-keyword">import</span> java.util.Map;<br><br><span class="hljs-meta">@RestController</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">UserController</span> &#123;<br>    <span class="hljs-meta">@GetMapping(&quot;/hello&quot;)</span><br>    <span class="hljs-keyword">public</span> Map&lt;String, Object&gt; <span class="hljs-title function_">hello</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;String, Object&gt;()&#123;&#123;<br>            put(<span class="hljs-string">&quot;code&quot;</span>, <span class="hljs-number">200</span>);<br>            put(<span class="hljs-string">&quot;msg&quot;</span>, <span class="hljs-string">&quot;你好呀!&quot;</span>);<br>        &#125;&#125;;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>前端Vue2脚手架：<br><code>vue.config.js</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> &#123; defineConfig &#125; = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;@vue/cli-service&#x27;</span>)<br><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = <span class="hljs-title function_">defineConfig</span>(&#123;<br><br>  <span class="hljs-comment">// 关闭eslint语法检查</span><br>  <span class="hljs-attr">lintOnSave</span>: <span class="hljs-literal">false</span>,<br>  <span class="hljs-attr">devServer</span>: &#123;<br>    <span class="hljs-comment">// 配置本地服务器的端口号</span><br>    <span class="hljs-attr">port</span>: <span class="hljs-number">5000</span>,<br>    <span class="hljs-comment">// 开启代理服务器</span><br>    <span class="hljs-comment">/* 方式一: 不写前缀, 当发起本地5000端口请求时，如果本地没有找到资源，就请求到8080端口</span><br><span class="hljs-comment">     缺点:</span><br><span class="hljs-comment">      1) 只能配置单个请求转发</span><br><span class="hljs-comment">      2) 不支持路径与静态资源重复, 如请求 http://localhost:5000/hello 时, 会先在本地查找hello的静态资源文件，如果没有的话才会转发到 http://localhost:8080/hello</span><br><span class="hljs-comment">    */</span> <br>    <span class="hljs-comment">// proxy: &#x27;http://localhost:8080&#x27;</span><br><br>    <span class="hljs-comment">/*</span><br><span class="hljs-comment">      方式二: 带前缀配置（可设置多个代理）</span><br><span class="hljs-comment">    */</span><br>   <span class="hljs-attr">proxy</span>: &#123;<br>    <span class="hljs-string">&#x27;/springboot&#x27;</span>: &#123;<br>      <span class="hljs-attr">target</span>: <span class="hljs-string">&#x27;http://localhost:8080&#x27;</span>,<br>      <span class="hljs-attr">ws</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// 用于支持 websocket</span><br>      <span class="hljs-attr">pathRewrite</span>: &#123;<span class="hljs-string">&#x27;^/springboot&#x27;</span>:<span class="hljs-string">&#x27;&#x27;</span>&#125;,<br>      <span class="hljs-attr">changeOrigin</span>: <span class="hljs-literal">false</span> <span class="hljs-comment">// 设置代理服务器是否发送真实的本地URL</span><br>    &#125;<br>   &#125;<br>  &#125;<br>&#125;)<br><br></code></pre></td></tr></table></figure>
<p><code>App.vue</code></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span> &#123;&#123;info&#125;&#125; <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;get()&quot;</span>&gt;</span>向 &#123;&#123;reqUrl&#125;&#125; 发送请求<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;axios&#x27;</span></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span><br><span class="language-javascript">  <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;App&#x27;</span>,</span><br><span class="language-javascript">  <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>)&#123;</span><br><span class="language-javascript">    <span class="hljs-keyword">return</span> &#123;</span><br><span class="language-javascript">      <span class="hljs-attr">reqUrl</span>: <span class="hljs-string">&#x27;http://localhost:5000/springboot/hello&#x27;</span>,</span><br><span class="language-javascript">      <span class="hljs-attr">info</span>: <span class="hljs-string">&#x27;请求内容&#x27;</span></span><br><span class="language-javascript">    &#125;</span><br><span class="language-javascript">  &#125;,</span><br><span class="language-javascript">  <span class="hljs-attr">methods</span>: &#123;</span><br><span class="language-javascript">    <span class="hljs-title function_">get</span>(<span class="hljs-params"></span>)&#123;</span><br><span class="language-javascript">      axios.<span class="hljs-title function_">get</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">reqUrl</span>).<span class="hljs-title function_">then</span>(</span><br><span class="language-javascript">        <span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> &#123;</span><br><span class="language-javascript">          <span class="hljs-title function_">alert</span>(<span class="hljs-string">&#x27;请求成功!&#x27;</span>)</span><br><span class="language-javascript">          <span class="hljs-variable language_">this</span>.<span class="hljs-property">info</span> = response.<span class="hljs-property">data</span></span><br><span class="language-javascript">        &#125;,</span><br><span class="language-javascript">        <span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> &#123;</span><br><span class="language-javascript">          <span class="hljs-title function_">alert</span>(<span class="hljs-string">&#x27;请求失败.&#x27;</span>)</span><br><span class="language-javascript">          <span class="hljs-variable language_">this</span>.<span class="hljs-property">info</span> = error.<span class="hljs-property">message</span></span><br><span class="language-javascript">        &#125;</span><br><span class="language-javascript">      )</span><br><span class="language-javascript">    &#125;</span><br><span class="language-javascript">  &#125;</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><strong>运行结果：</strong></p>
<p>![在这里插入图片描述](<a target="_blank" rel="noopener" href="https://img-blog.csdnimg.cn/097f769884794061a5ccb0c8565d853d.png#">https://img-blog.csdnimg.cn/097f769884794061a5ccb0c8565d853d.png#</a> &#x3D;60%x)<br>注：这里后端SpringBoot没有进行跨域相关的配置，这里是由Vue2内部提供的代理服务器实现的跨域。</p>
<h2 id="5-3-Vue2脚手架实现跨域总结"><a href="#5-3-Vue2脚手架实现跨域总结" class="headerlink" title="5.3 Vue2脚手架实现跨域总结"></a>5.3 Vue2脚手架实现跨域总结</h2><p><strong>方式一：在 vue.config.js中添加配置</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-attr">devServer</span>: &#123;<br>	<span class="hljs-attr">proxy</span>: <span class="hljs-string">&quot;http://localhost:5000&quot;</span><br>&#125;<br></code></pre></td></tr></table></figure>
<ul>
<li><p>优点：配置简单，请求资源时候直接发给前端8080，它会将其转发给5000</p>
</li>
<li><p>缺点：无法配置多个代理，不能灵活控制请求是否要进行代理</p>
</li>
<li><p>运行机制：按照上面的配置，当请求了前端不存在的资源时，那么该请求才会转发给配置的服务器（即优先匹配本地前端的资源）</p>
</li>
</ul>
<p><strong>方式二：在 vue.config.js中添加具体的代理规则</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = <span class="hljs-title function_">defineConfig</span>(&#123;<br>  <span class="hljs-comment">// 关闭eslint语法检查</span><br>  <span class="hljs-attr">lintOnSave</span>: <span class="hljs-literal">false</span>,<br>  <span class="hljs-attr">devServer</span>: &#123;<br>   <span class="hljs-comment">// 配置本地服务器的端口号</span><br>   <span class="hljs-attr">port</span>: <span class="hljs-number">5000</span>,<br>   <span class="hljs-attr">proxy</span>: &#123;<br>    <span class="hljs-string">&#x27;/springboot&#x27;</span>: &#123; <span class="hljs-comment">// 匹配所有以 &#x27;/springboot&#x27; 开头的请求路径</span><br>      <span class="hljs-attr">target</span>: <span class="hljs-string">&#x27;http://localhost:8080&#x27;</span>,	<span class="hljs-comment">// 代理目标的基础路径</span><br>      <span class="hljs-attr">ws</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// 用于支持 websocket</span><br>      <span class="hljs-attr">pathRewrite</span>: &#123;<span class="hljs-string">&#x27;^/springboot&#x27;</span>:<span class="hljs-string">&#x27;&#x27;</span>&#125;, <span class="hljs-comment">// 发送请求时正则替换路径</span><br>      <span class="hljs-attr">changeOrigin</span>: <span class="hljs-literal">true</span> <span class="hljs-comment">// 设置代理服务器是否发送真实的本地URL（推荐为true）</span><br>    &#125;,<br>    <br>    <span class="hljs-string">&#x27;/uni&#x27;</span>: &#123; <span class="hljs-comment">// 匹配所有以/uni开头的请求路径</span><br>	    <span class="hljs-attr">target</span>: <span class="hljs-string">&#x27;http://localhost:8081&#x27;</span>, <span class="hljs-comment">// 代理目标的基础路径</span><br>		<span class="hljs-attr">pathRewrite</span>: &#123;<span class="hljs-string">&#x27;^/uni&#x27;</span>:<span class="hljs-string">&#x27;&#x27;</span>&#125;	    <span class="hljs-comment">// 发送请求时正则替换路径</span><br>	    <span class="hljs-attr">changeOrigin</span>: <span class="hljs-literal">true</span><br>     &#125;<br>  &#125;<br>&#125;)<br></code></pre></td></tr></table></figure>

                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/categories/%E5%89%8D%E7%AB%AF/" class="category-chain-item">前端</a>
  
  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/tags/Vue/">#Vue</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>Vue2 笔记3 Vue2三种slot插槽的概念与运用 _ ES6 对象的解构赋值 _ 基于Vue2使用axios发送请求实现GitHub案例 _ 浏览器跨域问题与解决</div>
      <div>http://example.com/2022/07/24/Vue2 笔记3 Vue2三种slot插槽的概念与运用 _ ES6 对象的解构赋值 _ 基于Vue2使用axios发送请求实现GitHub案例 _ 浏览器跨域问题与解决/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>John Doe</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2022年7月24日</div>
        </div>
      
      
      <div class="license-meta-item">
        <div>许可协议</div>
        <div>
          
            
            
              <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
              <span class="hint--top hint--rounded" aria-label="BY - 署名">
                <i class="iconfont icon-by"></i>
              </span>
              </a>
            
          
        </div>
      </div>
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2022/07/24/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20%E7%AC%94%E8%AE%B06%20_%20%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%20%E5%9C%A8%20JDK%20%E6%BA%90%E7%A0%81%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8%20_%20JDBC%20%E7%9F%A5%E8%AF%86%E5%9B%9E%E9%A1%BE%20_%20java.sql%20%E9%87%8C%E7%9A%84%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%20Connection%EF%BC%8C%E5%85%B6%E5%86%85%E9%83%A8%E5%A3%B0%E6%98%8E%E4%BA%86%E4%B8%8D%E5%90%8C%E7%9A%84%20Statement%20%E6%8A%BD%E8%B1%A1%E4%BA%A7%E5%93%81/" title="设计模式 笔记6 _ 抽象工厂模式 在 JDK 源码中的应用 _ JDBC 知识回顾 _ java.sql 里的抽象工厂 Connection，其内部声明了不同的 Statement 抽象产品">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">设计模式 笔记6 _ 抽象工厂模式 在 JDK 源码中的应用 _ JDBC 知识回顾 _ java.sql 里的抽象工厂 Connection，其内部声明了不同的 Statement 抽象产品</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2022/07/24/Web%E5%BC%80%E5%8F%91%20%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81%20_%20SpringBoot%20%E6%95%B4%E5%90%88%20JWT%20_%20%E5%89%8D%E5%90%8E%E7%AB%AF%E4%B8%8D%E5%88%86%E7%A6%BB%E7%9A%84%E6%A1%88%E4%BE%8B%20_%20Cookie%E3%80%81Session%E3%80%81Token%20%E3%80%81JWT%E6%A6%82%E8%BF%B0%E4%B8%8E%E6%AF%94%E8%BE%83/" title="Web开发 身份验证 _ SpringBoot 整合 JWT _ 前后端不分离的案例 _ Cookie、Session、Token 、JWT概述与比较">
                        <span class="hidden-mobile">Web开发 身份验证 _ SpringBoot 整合 JWT _ 前后端不分离的案例 _ Cookie、Session、Token 、JWT概述与比较</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
    </div>
  
  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      headingSelector : CONFIG.toc.headingSelector || 'h1,h2,h3,h4,h5,h6',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      collapseDepth   : CONFIG.toc.collapseDepth || 0,
      scrollSmooth    : true,
      headingsOffset  : -boardTop
    });
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.10/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/js/local-search.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
